home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / BitString.h < prev    next >
C/C++ Source or Header  |  1994-05-22  |  20KB  |  762 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Doug Lea (dl@rocky.oswego.edu)
  5.  
  6. This file is part of the GNU C++ Library.  This library is free
  7. software; you can redistribute it and/or modify it under the terms of
  8. the GNU Library General Public License as published by the Free
  9. Software Foundation; either version 2 of the License, or (at your
  10. option) any later version.  This library is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE.  See the GNU Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #ifndef _BitString_h
  20. #ifdef __GNUG__
  21. #pragma interface
  22. #endif
  23.  
  24. #define _BitString_h 1
  25.  
  26. #include <stream.h>
  27. #include <limits.h>
  28.  
  29. #include <bitprims.h>
  30. #define BITSTRBITS  _BS_BITS_PER_WORD
  31.  
  32. struct BitStrRep
  33. {
  34.   unsigned int    len;          // length in bits
  35.   unsigned short  sz;           // allocated slots
  36.   _BS_word        s[1];         // bits start here
  37. };
  38.  
  39. extern BitStrRep*  BStr_alloc(BitStrRep*, const _BS_word*, int, int,int);
  40. extern BitStrRep*  BStr_resize(BitStrRep*, int);
  41. extern BitStrRep*  BStr_copy(BitStrRep*, const BitStrRep*);
  42. extern BitStrRep*  cmpl(const BitStrRep*, BitStrRep*);
  43. extern BitStrRep*  and(const BitStrRep*, const BitStrRep*, BitStrRep*);
  44. extern BitStrRep*  or(const BitStrRep*, const BitStrRep*, BitStrRep*);
  45. extern BitStrRep*  xor(const BitStrRep*, const BitStrRep*, BitStrRep*);
  46. extern BitStrRep*  diff(const BitStrRep*, const BitStrRep*, BitStrRep*);
  47. extern BitStrRep*  cat(const BitStrRep*, const BitStrRep*, BitStrRep*);
  48. extern BitStrRep*  cat(const BitStrRep*, unsigned int, BitStrRep*);
  49. extern BitStrRep*  lshift(const BitStrRep*, int, BitStrRep*);
  50.  
  51.  
  52. class BitString;
  53. class BitPattern;
  54.  
  55. class BitStrBit
  56. {
  57. protected:
  58.   BitString&        src;
  59.   unsigned int      pos;
  60.  
  61.  public:
  62.                     BitStrBit(BitString& v, int p);
  63.                     BitStrBit(const BitStrBit& b);
  64.                    ~BitStrBit();
  65.                     operator unsigned int() const;
  66.   int               operator =  (unsigned int b);
  67. };
  68.  
  69. class BitSubString
  70. {
  71.   friend class      BitString;
  72.   friend class      BitPattern;
  73.  
  74. protected:
  75.  
  76.   BitString&        S;
  77.   unsigned int      pos;
  78.   unsigned int      len;
  79.  
  80.                     BitSubString(BitString& x, int p, int l);
  81.                     BitSubString(const BitSubString& x);
  82. public:
  83.                     ~BitSubString();
  84.  
  85.   BitSubString&     operator =  (const BitString&);
  86.   BitSubString&     operator =  (const BitSubString&);
  87.  
  88.   int               length() const;
  89.   int               empty() const;
  90.  
  91.   int               OK() const;
  92. };
  93.  
  94. class BitString
  95. {
  96.   friend class       BitSubString;
  97.   friend class       BitPattern;
  98. protected:
  99.   BitStrRep*         rep;
  100.  
  101.   int                search(int, int, const _BS_word*, int, int) const;
  102.   int                match(int, int, int, const _BS_word*,int,int) const;
  103.   BitSubString       _substr(int first, int l);
  104.  
  105. public:
  106.  
  107. // constructors
  108.                      BitString();
  109.                      BitString(const BitString&);
  110.                      BitString(const BitSubString& y);
  111.  
  112.                     ~BitString();
  113.  
  114.   BitString&         operator =  (unsigned int bit);
  115.   BitString&         operator =  (const BitString& y);
  116.   BitString&         operator =  (const BitSubString& y);
  117.  
  118. // equality & subset tests
  119.  
  120.   friend int         operator == (const BitString&, const BitString&);
  121.   friend int         operator != (const BitString&, const BitString&);
  122.   friend int         operator <  (const BitString&, const BitString&);
  123.   friend int         operator <= (const BitString&, const BitString&);
  124.   friend int         operator >  (const BitString&, const BitString&);
  125.   friend int         operator >= (const BitString&, const BitString&);
  126.  
  127. // procedural versions of operators
  128.  
  129.  
  130.   friend void        and(const BitString&, const BitString&, BitString&);
  131.   friend void        or(const BitString&, const BitString&, BitString&);
  132.   friend void        xor(const BitString&, const BitString&, BitString&);
  133.   friend void        diff(const BitString&, const BitString&, BitString&);
  134.   friend void        cat(const BitString&, const BitString&, BitString&);
  135.   friend void        cat(const BitString&, unsigned int, BitString&);
  136.   friend void        lshift(const BitString&, int, BitString&);
  137.   friend void        rshift(const BitString&, int, BitString&);
  138.  
  139.   friend void        complement(const BitString&, BitString&);
  140.  
  141.   friend int         lcompare(const BitString&, const BitString&); 
  142.  
  143. // assignment-based operators
  144. // (constuctive versions decalred inline below
  145.  
  146.   BitString&         operator |= (const BitString&);
  147.   BitString&         operator &= (const BitString&);
  148.   BitString&         operator -= (const BitString&);
  149.   BitString&         operator ^= (const BitString&);
  150.   BitString&         operator += (const BitString&);
  151.   BitString&         operator += (unsigned int b);
  152.   BitString&         operator <<=(int s);
  153.   BitString&         operator >>=(int s);
  154.  
  155.   void               complement();
  156.  
  157. // individual bit manipulation
  158.  
  159.   void               set(int pos);
  160.   void               set(int from, int to);
  161.   void               set();
  162.  
  163.   void               clear(int pos);
  164.   void               clear(int from, int to);
  165.   void               clear(); 
  166.  
  167.   void               invert(int pos);
  168.   void               invert(int from, int to);
  169.  
  170.   int                test(int pos) const;
  171.   int                test(int from, int to) const;
  172.  
  173.   void               assign(int p, unsigned int bit);
  174.  
  175. // indexing
  176.  
  177.   BitStrBit          operator [] (int pos);
  178.  
  179. // iterators
  180.  
  181.   int                first(unsigned int bit = 1) const;
  182.   int                last(unsigned int b = 1) const;
  183.  
  184.   int                next(int pos, unsigned int b = 1) const;
  185.   int                prev(int pos, unsigned int b = 1) const;
  186.   int                previous(int pos, unsigned int b = 1) const
  187.     { return prev(pos, b); } /* Obsolete synonym */
  188.  
  189. // searching & matching
  190.  
  191.   int                index(unsigned int bit, int startpos = 0) const ;      
  192.   int                index(const BitString&, int startpos = 0) const;
  193.   int                index(const BitSubString&, int startpos = 0) const;
  194.   int                index(const BitPattern&, int startpos = 0) const;
  195.  
  196.   int                contains(const BitString&) const;
  197.   int                contains(const BitSubString&) const;
  198.   int                contains(const BitPattern&) const;
  199.  
  200.   int                contains(const BitString&, int pos) const;
  201.   int                contains(const BitSubString&, int pos) const;
  202.   int                contains(const BitPattern&, int pos) const;
  203.  
  204.   int                matches(const BitString&, int pos = 0) const;
  205.   int                matches(const BitSubString&, int pos = 0) const;
  206.   int                matches(const BitPattern&, int pos = 0) const;
  207.  
  208. // BitSubString extraction
  209.  
  210.   BitSubString       at(int pos, int len);
  211.   BitSubString       at(const BitString&, int startpos = 0); 
  212.   BitSubString       at(const BitSubString&, int startpos = 0); 
  213.   BitSubString       at(const BitPattern&, int startpos = 0); 
  214.  
  215.   BitSubString       before(int pos);
  216.   BitSubString       before(const BitString&, int startpos = 0);
  217.   BitSubString       before(const BitSubString&, int startpos = 0);
  218.   BitSubString       before(const BitPattern&, int startpos = 0);
  219.  
  220.   BitSubString       after(int pos);
  221.   BitSubString       after(const BitString&, int startpos = 0);
  222.   BitSubString       after(const BitSubString&, int startpos = 0);
  223.   BitSubString       after(const BitPattern&, int startpos = 0);
  224.  
  225. // other friends & utilities
  226.  
  227.   friend BitString   common_prefix(const BitString&, const BitString&, 
  228.                                    int pos = 0);
  229.   friend BitString   common_suffix(const BitString&, const BitString&, 
  230.                                    int pos = -1);
  231.   friend BitString   reverse(const BitString&);
  232.  
  233.   void               right_trim(unsigned int bit);
  234.   void               left_trim(unsigned int bit);
  235.  
  236. // status
  237.  
  238.   int                empty() const ;
  239.   int                count(unsigned int bit = 1) const;
  240.   int                length() const;
  241.  
  242. // convertors & IO
  243.  
  244.   friend BitString   atoBitString(const char* s, char f='0', char t='1');
  245.   // BitStringtoa is deprecated; do not use in new programs!
  246.   friend const char* BitStringtoa(const BitString&, char f='0', char t='1');
  247.   void             printon(ostream&, char f='0', char t='1') const;
  248.  
  249.   friend BitString   shorttoBitString(unsigned short);
  250.   friend BitString   longtoBitString(unsigned long);
  251.  
  252.   friend ostream&    operator << (ostream& s, const BitString&);
  253.  
  254. // misc
  255.  
  256.   void      error(const char* msg) const;
  257.  
  258. // indirect friends
  259.  
  260.   friend BitPattern  atoBitPattern(const char* s,
  261.                                   char f='0',char t='1',char x='X');
  262.   friend const char* BitPatterntoa(const BitPattern& p, 
  263.                                   char f='0',char t='1',char x='X');
  264.   int                OK() const;
  265. };
  266.  
  267.  
  268. class BitPattern
  269. {
  270. public:
  271.   BitString          pattern;
  272.   BitString          mask;
  273.  
  274.                      BitPattern();
  275.                      BitPattern(const BitPattern&);
  276.                      BitPattern(const BitString& p, const BitString& m);
  277.  
  278.                     ~BitPattern();
  279.  
  280.   friend const char* BitPatterntoa(const BitPattern& p, 
  281.                                  char f/*='0'*/,char t/*='1'*/,char x/*='X'*/);
  282.   void             printon(ostream&, char f='0',char t='1',char x='X') const;
  283.   friend BitPattern atoBitPattern(const char* s, char f,char t, char x);
  284.   friend ostream&   operator << (ostream& s, const BitPattern&);
  285.  
  286.   int               search(const _BS_word*, int, int) const;
  287.   int               match(const _BS_word* xs, int, int, int) const;
  288.  
  289.   int               OK() const;
  290. };
  291.  
  292. BitString  operator & (const BitString& x, const BitString& y);
  293. BitString  operator | (const BitString& x, const BitString& y);
  294. BitString  operator ^ (const BitString& x, const BitString& y);
  295. BitString  operator << (const BitString& x, int y);
  296. BitString  operator >> (const BitString& x, int y);
  297. BitString  operator - (const BitString& x, const BitString& y);
  298. BitString  operator + (const BitString& x, const BitString& y);
  299. BitString  operator + (const BitString& x, unsigned int y);
  300. BitString  operator ~ (const BitString& x);
  301. int operator != (const BitString& x, const BitString& y);
  302. int operator>(const BitString& x, const BitString& y);
  303. int operator>=(const BitString& x, const BitString& y);
  304.  
  305. extern BitStrRep    _nilBitStrRep;
  306. extern BitString    _nil_BitString;
  307.  
  308. // primitive bit extraction
  309.  
  310. // These must be inlined regardless of optimization.
  311.  
  312. inline int BitStr_index(int l) { return (unsigned)(l) / BITSTRBITS; }
  313.  
  314. inline int BitStr_pos(int l) { return l & (BITSTRBITS - 1); }
  315.  
  316.  
  317. // constructors & assignment
  318.  
  319. inline BitString::BitString() :rep(&_nilBitStrRep) {}
  320.  
  321. inline BitString::BitString(const BitString& x) :rep(BStr_copy(0, x.rep)) {}
  322.  
  323. inline BitString::BitString(const BitSubString& y) 
  324.    :rep (BStr_alloc(0, y.S.rep->s, y.pos, y.pos+y.len, y.len)) {}
  325.  
  326. inline BitString::~BitString()
  327.   if (rep != &_nilBitStrRep) delete rep;
  328. }
  329.  
  330. inline BitString shorttoBitString(unsigned short w) 
  331.   BitString r;
  332.   _BS_word ww = w;
  333. #if _BS_BIGENDIAN
  334.   abort();
  335. #endif
  336.   r.rep = BStr_alloc(0, &ww, 0, 8 * sizeof(short), 8 * sizeof(short));
  337.   return r;
  338. }
  339.  
  340. inline BitString longtoBitString(unsigned long w) 
  341.   BitString r;
  342. #if 1
  343.   _BS_word u = w;
  344.   r.rep = BStr_alloc(0, &u, 0, BITSTRBITS, BITSTRBITS);
  345. #else
  346.   unsigned short u[2];
  347.   u[0] = w & ((unsigned short)(~(0)));
  348.   u[1] = w >> BITSTRBITS;
  349.   r.rep = BStr_alloc(0, &u[0], 0, 2*BITSTRBITS, 2*BITSTRBITS);
  350. #endif
  351.   return r;
  352. }
  353.  
  354. inline BitString& BitString::operator =  (const BitString& y)
  355.   rep = BStr_copy(rep, y.rep);
  356.   return *this;
  357. }
  358.  
  359. inline BitString& BitString::operator = (unsigned int b)
  360.   _BS_word bit = b;
  361.   rep = BStr_alloc(rep, &bit, 0, 1, 1);
  362.   return *this;
  363. }
  364.  
  365. inline BitString&  BitString::operator=(const BitSubString&  y)
  366. {
  367.   rep = BStr_alloc(rep, y.S.rep->s, y.pos, y.pos+y.len, y.len);
  368.   return *this;
  369. }
  370.  
  371. inline BitSubString::BitSubString(const BitSubString& x) 
  372.     :S(x.S), pos(x.pos), len(x.len) {}
  373.  
  374. inline BitSubString::BitSubString(BitString& x, int p, int l)
  375.      : S(x), pos(p), len(l) {}
  376.  
  377. inline BitSubString::~BitSubString() {}
  378.  
  379. inline BitPattern::BitPattern(const BitString& p, const BitString& m)
  380.     :pattern(p), mask(m) {}
  381.  
  382. inline BitPattern::BitPattern(const BitPattern& b)
  383.     :pattern(b.pattern), mask(b.mask) {}
  384.  
  385. inline BitPattern::BitPattern() {}
  386. inline BitPattern::~BitPattern() {}
  387.  
  388.  
  389. // procedural versions of operators
  390.  
  391. inline void and(const BitString& x, const BitString& y, BitString& r)
  392. {
  393.   r.rep = and(x.rep, y.rep, r.rep);
  394. }
  395.  
  396. inline void or(const BitString& x, const BitString& y, BitString& r)
  397. {
  398.   r.rep = or(x.rep, y.rep, r.rep);
  399. }
  400.  
  401. inline void xor(const BitString& x, const BitString& y, BitString& r)
  402. {
  403.   r.rep = xor(x.rep, y.rep, r.rep);
  404. }
  405.  
  406. inline void diff(const BitString& x, const BitString& y, BitString& r)
  407. {
  408.   r.rep = diff(x.rep, y.rep, r.rep);
  409. }
  410.  
  411. inline void cat(const BitString& x, const BitString& y, BitString& r)
  412. {
  413.   r.rep = cat(x.rep, y.rep, r.rep);
  414. }
  415.  
  416. inline void cat(const BitString& x, unsigned int y, BitString& r)
  417. {
  418.   r.rep = cat(x.rep, y, r.rep);
  419. }
  420.  
  421. inline void rshift(const BitString& x, int y, BitString& r)
  422. {
  423.   r.rep = lshift(x.rep, -y, r.rep);
  424. }
  425.  
  426. inline void lshift(const BitString& x, int y, BitString& r)
  427. {
  428.   r.rep = lshift(x.rep, y, r.rep);
  429. }
  430.  
  431. inline void complement(const BitString& x, BitString& r)
  432. {
  433.   r.rep = cmpl(x.rep, r.rep);
  434. }
  435.  
  436. // operators
  437.  
  438.  
  439. inline BitString& BitString::operator &= (const BitString& y)
  440. {
  441.   and(*this, y, *this);
  442.   return *this;
  443. }
  444.  
  445.  
  446. inline BitString& BitString::operator |= (const BitString& y)
  447. {
  448.   or(*this, y, *this);
  449.   return *this;
  450. }
  451.  
  452. inline BitString& BitString::operator ^= (const BitString& y)
  453. {
  454.   xor(*this, y, *this);
  455.   return *this;
  456. }
  457.  
  458. inline BitString& BitString::operator <<= (int y)
  459. {
  460.   lshift(*this, y, *this);
  461.   return *this;
  462. }
  463.  
  464. inline BitString& BitString::operator >>= (int y)
  465. {
  466.   rshift(*this, y, *this);
  467.   return *this;
  468. }
  469.  
  470. inline BitString& BitString::operator -= (const BitString& y)
  471. {
  472.   diff(*this, y, *this);
  473.   return *this;
  474. }
  475.  
  476. inline BitString& BitString::operator += (const BitString& y)
  477. {
  478.   cat(*this, y, *this);
  479.   return *this;
  480. }
  481.  
  482. inline BitString& BitString::operator += (unsigned int y)
  483. {
  484.   cat(*this, y, *this);
  485.   return *this;
  486. }
  487.  
  488. inline void BitString::complement()
  489. {
  490.   ::complement(*this, *this);
  491. }
  492.  
  493. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  494.  
  495. inline BitString  operator & (const BitString& x, const BitString& y) return r
  496. {
  497.   and(x, y, r);
  498. }
  499.  
  500. inline BitString  operator | (const BitString& x, const BitString& y) return r
  501. {
  502.   or(x, y, r);
  503. }
  504.  
  505. inline BitString  operator ^ (const BitString& x, const BitString& y) return r
  506. {
  507.   xor(x, y, r);
  508. }
  509.  
  510. inline BitString  operator << (const BitString& x, int y) return r
  511. {
  512.   lshift(x, y, r);
  513. }
  514.  
  515. inline BitString  operator >> (const BitString& x, int y) return r
  516. {
  517.   rshift(x, y, r);
  518. }
  519.  
  520. inline BitString  operator - (const BitString& x, const BitString& y) return r
  521. {
  522.   diff(x, y, r);
  523. }
  524.  
  525. inline BitString  operator + (const BitString& x, const BitString& y) return r
  526. {
  527.   cat(x, y, r);
  528. }
  529.  
  530. inline BitString  operator + (const BitString& x, unsigned int y) return r
  531. {
  532.   cat(x, y, r);
  533. }
  534.  
  535. inline BitString  operator ~ (const BitString& x) return r
  536. {
  537.   complement(x, r);
  538. }
  539.  
  540. #else /* NO_NRV */
  541.  
  542. inline BitString  operator & (const BitString& x, const BitString& y) 
  543. {
  544.   BitString r; and(x, y, r); return r;
  545. }
  546.  
  547. inline BitString  operator | (const BitString& x, const BitString& y) 
  548. {
  549.   BitString r; or(x, y, r); return r;
  550. }
  551.  
  552. inline BitString  operator ^ (const BitString& x, const BitString& y) 
  553. {
  554.   BitString r; xor(x, y, r); return r;
  555. }
  556.  
  557. inline BitString  operator << (const BitString& x, int y) 
  558. {
  559.   BitString r; lshift(x, y, r); return r;
  560. }
  561.  
  562. inline BitString  operator >> (const BitString& x, int y) 
  563. {
  564.   BitString r; rshift(x, y, r); return r;
  565. }
  566.  
  567. inline BitString  operator - (const BitString& x, const BitString& y) 
  568. {
  569.   BitString r; diff(x, y, r); return r;
  570. }
  571.  
  572. inline BitString  operator + (const BitString& x, const BitString& y) 
  573. {
  574.   BitString r; cat(x, y, r); return r;
  575. }
  576.  
  577. inline BitString  operator + (const BitString& x, unsigned int y) 
  578. {
  579.   BitString r; cat(x, y, r); return r;
  580. }
  581.  
  582. inline BitString  operator ~ (const BitString& x) 
  583. {
  584.   BitString r; complement(x, r); return r;
  585. }
  586.  
  587. #endif
  588.  
  589. // status, matching
  590.  
  591. inline int BitString::length() const
  592.   return rep->len;
  593. }
  594.  
  595. inline int BitString::empty() const
  596.   return rep->len == 0;
  597. }
  598.  
  599. inline int BitString::index(const BitString& y, int startpos) const
  600. {   
  601.   return search(startpos, rep->len, y.rep->s, 0, y.rep->len);
  602. }
  603.  
  604. inline int BitString::index(const BitSubString& y, int startpos) const
  605. {   
  606.   return search(startpos, rep->len, y.S.rep->s, y.pos, y.pos+y.len);
  607. }
  608.  
  609. inline int BitString::contains(const BitString& y) const
  610. {   
  611.   return search(0, rep->len, y.rep->s, 0, y.rep->len) >= 0;
  612. }
  613.  
  614. inline int BitString::contains(const BitSubString& y) const
  615. {   
  616.   return search(0, rep->len, y.S.rep->s, y.pos, y.pos+y.len) >= 0;
  617. }
  618.  
  619. inline int BitString::contains(const BitString& y, int p) const
  620. {
  621.   return match(p, rep->len, 0, y.rep->s, 0, y.rep->len);
  622. }
  623.  
  624. inline int BitString::matches(const BitString& y, int p) const
  625. {
  626.   return match(p, rep->len, 1, y.rep->s, 0, y.rep->len);
  627. }
  628.  
  629. inline int BitString::contains(const BitSubString& y, int p) const
  630. {
  631.   return match(p, rep->len, 0, y.S.rep->s, y.pos, y.pos+y.len);
  632. }
  633.  
  634. inline int BitString::matches(const BitSubString& y, int p) const
  635. {
  636.   return match(p, rep->len, 1, y.S.rep->s, y.pos, y.pos+y.len);
  637. }
  638.  
  639. inline int BitString::contains(const BitPattern& r) const
  640. {
  641.   return r.search(rep->s, 0, rep->len) >= 0;
  642. }
  643.  
  644. inline int BitString::contains(const BitPattern& r, int p) const
  645. {
  646.   return r.match(rep->s, p, rep->len, 0);
  647. }
  648.  
  649. inline int BitString::matches(const BitPattern& r, int p) const
  650. {
  651.   return r.match(rep->s, p, rep->len, 1);
  652. }
  653.  
  654. inline int BitString::index(const BitPattern& r, int startpos) const
  655. {
  656.   return r.search(rep->s, startpos, rep->len);
  657. }
  658.  
  659. inline  int BitSubString::length() const
  660.   return len;
  661. }
  662.  
  663. inline  int BitSubString::empty() const
  664.   return len == 0;
  665. }
  666.  
  667. inline int operator != (const BitString& x, const BitString& y)
  668. {
  669.   return !(x == y);
  670. }
  671.  
  672. inline int operator>(const BitString& x, const BitString& y)
  673. {
  674.   return y < x;
  675. }
  676.  
  677. inline int operator>=(const BitString& x, const BitString& y)
  678. {
  679.   return y <= x;
  680. }
  681.  
  682. inline int BitString::first(unsigned int b) const
  683. {
  684.   return next(-1, b);
  685. }
  686.  
  687. inline int BitString::last(unsigned int b) const
  688. {
  689.   return prev(rep->len, b);
  690. }
  691.  
  692. inline int BitString::index(unsigned int bit, int startpos) const
  693. {
  694.   if (startpos >= 0)
  695.     return next(startpos - 1, bit);
  696.   else
  697.     return prev(rep->len + startpos + 1, bit);
  698. }
  699.  
  700. inline void BitString::right_trim(unsigned int b) 
  701. {
  702.   int nb = (b == 0)? 1 : 0;
  703.   rep = BStr_resize(rep, prev(rep->len, nb) + 1);
  704. }
  705.  
  706. inline void BitString::left_trim(unsigned int b)
  707. {
  708.   int nb = (b == 0)? 1 : 0;
  709.   int p = next(-1, nb);
  710.   rep = BStr_alloc(rep, rep->s, p, rep->len, rep->len - p);
  711. }
  712.  
  713. inline int BitString::test(int i) const
  714. {
  715.   return ((unsigned)(i) >= rep->len)? 0 : 
  716.          ((rep->s[BitStr_index(i)] & (1 << (BitStr_pos(i)))) != 0);
  717. }
  718.  
  719.  
  720. // subscripting
  721.  
  722. inline BitStrBit::BitStrBit(const BitStrBit& b) :src(b.src), pos(b.pos) {}
  723.  
  724. inline BitStrBit::BitStrBit(BitString& v, int p) :src(v), pos(p) {}
  725.  
  726. inline BitStrBit::~BitStrBit() {}
  727.  
  728. inline BitStrBit::operator unsigned int() const
  729. {
  730.   return src.test(pos);
  731. }
  732.  
  733. inline int BitStrBit::operator = (unsigned int b)
  734. {
  735.   src.assign(pos, b); return b;
  736. }
  737.  
  738. inline BitStrBit BitString::operator [] (int i)
  739. {
  740.   if ((unsigned)(i) >= rep->len) error("illegal bit index");
  741.   return BitStrBit(*this, i);
  742. }
  743.  
  744. inline BitSubString BitString::_substr(int first, int l)
  745. {
  746.   if (first < 0 || l <= 0 || (unsigned)(first + l) > rep->len)
  747.     return BitSubString(_nil_BitString, 0, 0) ;
  748.   else 
  749.     return BitSubString(*this, first, l);
  750. }
  751.  
  752. #endif
  753.